home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / windows4 / prndrv.zip / MAINWND.C < prev    next >
Text File  |  1992-02-20  |  31KB  |  1,001 lines

  1. //*************************************************************
  2. //  File name: mainwnd.c
  3. //
  4. //  Description:
  5. //
  6. //      WinMain and window procedure routines.
  7. //
  8. // This sample demonstrates the usage of the DeviceCapabilities() 
  9. // function that is exported by most printer drivers.  The application
  10. // dumps all the possible information that the DeviceCapabilities() 
  11. // function supports.  This includes basic driver information, 
  12. // paper information, bin information, and DEVMODE information. 
  13. //
  14. //
  15. // Development Team:
  16. //
  17. //      Don Miller
  18. //
  19. //
  20. // Written by Microsoft Product Support Services, Windows Developer Support
  21. // Copyright (c) 1992 Microsoft Corporation. All rights reserved.
  22. //*************************************************************
  23.  
  24. #include <windows.h>
  25. #include <string.h>
  26. #include <io.h>
  27. #include <drivinit.h>
  28. #include "globals.h"
  29. #include "about.h"
  30. #include "mainwnd.h"
  31. #include "devmode.h"
  32.  
  33.  
  34. //*************************************************************
  35. //  Function: MainWndProc
  36. //
  37. //  Purpose : Message handler for main, overlapped window.
  38. //
  39. //  Parms   : hWnd    == Handle to _this_ window.
  40. //            message == Message to process.
  41. //            wParam  == WORD parameter -- depends on message
  42. //            lParam  == LONG parameter -- depends on message
  43. //
  44. //  Returns : Depends on message.
  45. //
  46. //  Comments:
  47. //
  48. //
  49. //  History:    Date       Author     Comment
  50. //              1/29/92    Don Miller
  51. //*************************************************************
  52.  
  53. long FAR PASCAL MainWndProc (HWND hWnd, 
  54.                          unsigned message, 
  55.                              WORD wParam, 
  56.                              LONG lParam)
  57. {
  58.    
  59.    switch (message) 
  60.    {
  61.       case WM_SIZE:
  62.          // get size of client window
  63.          ixClient = LOWORD(lParam);
  64.          iyClient = HIWORD(lParam);
  65.          break;
  66.  
  67.       case WM_CREATE:
  68.       {
  69.            TEXTMETRIC tm;
  70.            HDC        hdc;
  71.  
  72.            //initialize globals
  73.            hDriver        = NULL;
  74.            nCurrentDevice = 0;
  75.            nCurrentInfo   = IDM_DRVINFO;
  76.  
  77.            // get fixed font
  78.            hdc = GetDC (hWnd) ;
  79.            SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
  80.            GetTextMetrics (hdc, &tm) ;
  81.            cxChar = tm.tmAveCharWidth ;
  82.            cyChar = tm.tmHeight + tm.tmExternalLeading ;
  83.            ReleaseDC (hWnd, hdc) ;
  84.  
  85.            lParam = NULL ;
  86.       }                                        // fall through
  87.  
  88.       case WM_WININICHANGE:
  89.       {
  90.            HMENU hMenu;
  91.  
  92.           // start building device menu list
  93.           if (lParam != NULL && lstrcmp ((LPSTR) lParam, "devices") != 0)
  94.                return 0 ;
  95.  
  96.           hMenu = GetSubMenu (GetMenu (hWnd), 0) ;
  97.  
  98.            while (GetMenuItemCount (hMenu) > 1)
  99.                DeleteMenu (hMenu, 1, MF_BYPOSITION) ;
  100.  
  101.            GetProfileString ("devices", NULL, "", szAllDevices,
  102.                     sizeof szAllDevices) ;
  103.  
  104.            // add devices to File menu
  105.            n = IDM_TOP;
  106.            szPtr = szAllDevices ;
  107.            while (*szPtr)
  108.            {
  109.                AppendMenu (hMenu, n % 16 ? 0 : MF_MENUBARBREAK, n, szPtr);
  110.                n++ ;
  111.                szPtr += strlen (szPtr) + 1 ;
  112.            }
  113.            // add Exit and About menu choices
  114.            AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ;
  115.            AppendMenu (hMenu, MF_STRING, IDM_EXIT, (LPSTR)"E&xit") ;
  116.            AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ;
  117.            AppendMenu (hMenu, MF_STRING, IDM_ABOUT, (LPSTR)"&About") ;
  118.  
  119.       }
  120.       break;
  121.  
  122.          // Dispatch WM_COMMAND messages to our command handler, DoCommands().
  123.       case WM_COMMAND:
  124.          return DoCommands (hWnd, message, wParam, lParam);
  125.  
  126.  
  127.       case WM_PAINT:
  128.       {
  129.          PAINTSTRUCT ps;
  130.          int iOldMode;
  131.  
  132.          BeginPaint(hWnd, &ps);
  133.  
  134.          // set mode to transparent and select fixed font
  135.          iOldMode = SetBkMode(ps.hdc, TRANSPARENT);
  136.          SelectObject (ps.hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
  137.  
  138.          // display information for current choice
  139.          if (hDriver)
  140.          {
  141.             switch (nCurrentInfo)
  142.             {
  143.                // display driver info
  144.                case IDM_DRVINFO:
  145.                   DumpDriverInfo(ps.hdc);
  146.                   break;
  147.  
  148.                // display paper size info
  149.                case IDM_PAPERSIZES:
  150.                   DumpPaperInfo(ps.hdc);
  151.                   break;
  152.  
  153.                // display bin info
  154.                case IDM_BINS:
  155.                   DumpBinInfo(ps.hdc);
  156.                   break;
  157.  
  158.                // display DEVMODE info
  159.                case IDMDEVMODE:
  160.                   DumpDevmodeInfo(hWnd, ps.hdc);
  161.                   break;
  162.  
  163.                default:
  164.                   break;
  165.             }
  166.          }
  167.          else // No printer driver has been selected
  168.             TextOut(ps.hdc, 10, 10, (LPSTR)"No driver selected!", 19);
  169.  
  170.          SetBkMode(ps.hdc, iOldMode);
  171.  
  172.          EndPaint(hWnd, &ps);
  173.       }
  174.       break;
  175.  
  176.       // On WM_DESTROY, terminate this app by posting a WM_QUIT message.
  177.       case WM_DESTROY:
  178.          PostQuitMessage(0);
  179.          break;
  180.  
  181.       // We didn't handle, pass to DefWindowProc.
  182.       default:
  183.          return DefWindowProc (hWnd, message, wParam, lParam);
  184.     }
  185.     return (NULL);
  186. }
  187.  
  188. //************************************************************
  189. //  Function: DoCommands
  190. //
  191. //  Purpose : Called by MainWndProc() to handle all WM_COMMAND type
  192. //            messages.
  193. //
  194. //  Parms   : hWnd    == Handle to _this_ window.
  195. //            message == Message to process.
  196. //            wParam  == WORD parameter -- depends on message
  197. //            lParam  == LONG parameter -- depends on message
  198. //
  199. //  Returns : Depends on message.
  200. //
  201. //  Comments:
  202. //
  203. //
  204. //  History:    Date       Author     Comment
  205. //              1/29/92    Don Miller
  206. //*************************************************************
  207.  
  208. long DoCommands (HWND hWnd,
  209.              unsigned message, 
  210.                  WORD wParam, 
  211.                  LONG lParam)
  212. {
  213.  
  214.    // a device was selected
  215.    if (wParam < IDM_EXIT)
  216.    {
  217.       HMENU hMenu;
  218.  
  219.       hMenu = GetMenu(hWnd);
  220.  
  221.       // check new printer name in File menu
  222.       CheckMenuItem(hMenu, nCurrentDevice, MF_UNCHECKED);
  223.       nCurrentDevice = wParam;
  224.       CheckMenuItem(hMenu, nCurrentDevice, MF_CHECKED);
  225.  
  226.       // get printer driver name
  227.       GetMenuString(hMenu, nCurrentDevice, (LPSTR)szDevice, sizeof(szDevice),
  228.                     MF_BYCOMMAND);
  229.  
  230.       GetProfileString("devices", (LPSTR)szDevice, "", (LPSTR)szDriver,
  231.                        sizeof(szDriver));
  232.  
  233.       szOutput = strtok(szDriver, ",");
  234.       szOutput = strtok(NULL, ",");
  235.  
  236.       lstrcpy((LPSTR)szDriverFile, (LPSTR)szDriver);
  237.       lstrcat((LPSTR)szDriverFile, (LPSTR)".DRV");
  238.  
  239.       // check if driver already loaded
  240.       if (hDriver >=32)
  241.       {
  242.          FreeLibrary(hDriver);
  243.          hDriver = NULL;
  244.       }
  245.  
  246.       // load printer driver 
  247.       if ((hDriver = LoadLibrary((LPSTR)szDriverFile)) < 32)
  248.          return 0;
  249.  
  250.       // set window caption to printer device name
  251.       SetWindowText(hWnd, (LPSTR)szDevice);
  252.       CheckMenuItem(hMenu, nCurrentInfo, MF_CHECKED);
  253.       InvalidateRect(hWnd, NULL, TRUE);
  254.    }
  255.    else
  256.    {
  257.       switch (wParam) 
  258.          {
  259.          // check respective menu choice
  260.          case IDM_DRVINFO:
  261.          case IDM_PAPERSIZES:
  262.          case IDM_BINS:
  263.          case IDMDEVMODE:
  264.          {
  265.             HMENU hMenu;
  266.  
  267.             hMenu = GetMenu(hWnd);
  268.  
  269.             // check appropriate choice
  270.             CheckMenuItem(hMenu, nCurrentInfo, MF_UNCHECKED);
  271.             nCurrentInfo = wParam;
  272.             CheckMenuItem(hMenu, nCurrentInfo, MF_CHECKED);
  273.  
  274.             // force a repaint
  275.             InvalidateRect(hWnd, NULL, TRUE);
  276.          }
  277.          break;
  278.  
  279.          // Put up the About box.
  280.          case IDM_ABOUT:
  281.             {
  282.             FARPROC lpDlgProc;
  283.  
  284.             lpDlgProc = MakeProcInstance (AboutDlg, ghInst);
  285.  
  286.             DialogBox (ghInst,            // current instance
  287.                        AboutBoxName,      // resource to use 
  288.                        hWnd,              // parent handle   
  289.                        lpDlgProc);        // About() instance address
  290.  
  291.             FreeProcInstance (lpDlgProc);
  292.             break;
  293.             }
  294.  
  295.             // User picked File.Exit, terminate this app.
  296.  
  297.          case IDM_EXIT:
  298.             // check if driver already loaded
  299.             if (hDriver >=32)
  300.             {
  301.                FreeLibrary(hDriver);
  302.                hDriver = NULL;
  303.             }
  304.             DestroyWindow (hWnd);
  305.             break;
  306.  
  307.          default:
  308.             return DefWindowProc (hWnd, message, wParam, lParam);
  309.          } // end switch
  310.      }  // end of if
  311.  
  312.    return NULL;
  313. }
  314.  
  315.  
  316. //*************************************************************
  317. //
  318. //  DumpDriverInfo
  319. //
  320. //  Purpose: This function retrieves driver information (file name,
  321. //           file date, file size) from the driver and from other
  322. //           runtime functions.
  323. //        
  324. //
  325. //
  326. //  Parameters:
  327. //      HDC hDC
  328. //      
  329. //
  330. //  Return: (BOOL)
  331. //
  332. //
  333. //  Comments:
  334. //
  335. //
  336. //  History:    Date       Author     Comment
  337. //              1/29/92    Don Miller
  338. //*************************************************************
  339.  
  340. BOOL DumpDriverInfo(HDC hDC)
  341. {
  342.    LPFNDEVCAPS  lpfnDeviceCaps;
  343.    DWORD        dwBufSize = 0;
  344.    BOOL         bResult = 1;
  345.    OFSTRUCT     of;
  346.    char         szBuffer[16];
  347.    int          i, ixPos, iyPos, iyOrg, ihDRVFile;
  348.    unsigned int uiTime, uiDate;
  349.  
  350.  
  351.    // set column positions
  352.    ixPos = cxChar;
  353.    iyPos = 0;
  354.  
  355.    // display header text centered
  356.    DisplayTextHeader(hDC, ixClient/2, iyPos, (LPSTR)"Driver Info");
  357.  
  358.    // set column positions
  359.    iyOrg = 2*cyChar;
  360.    iyPos = iyOrg;
  361.  
  362.    // display text
  363.    for (i=0; i < 4; i++)
  364.    {
  365.      TextOut(hDC, ixPos, iyPos, (LPSTR)szDrvInfo[i], lstrlen((LPSTR)szDrvInfo[i]));  
  366.      iyPos+=iyOrg;
  367.    }
  368.    // get longest string extent and set x position
  369.    ixPos = LOWORD(GetTextExtent(hDC, (LPSTR)"Driver Version:", 15)) + 2*cxChar;
  370.    iyPos = iyOrg;
  371.  
  372.    // display printer driver name
  373.    TextOut(hDC, ixPos, iyPos, (LPSTR)szDriverFile, lstrlen((LPSTR)szDriverFile));  
  374.  
  375.    // open the printer driver file
  376.    ihDRVFile = OpenFile((LPSTR)szDriverFile, &of, OF_READ);
  377.  
  378.    // get driver size
  379.    wsprintf((LPSTR)szBuffer, "%ld bytes", filelength(ihDRVFile));
  380.    TextOut(hDC, ixPos, iyPos+=iyOrg, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));  
  381.  
  382.    //get driver date
  383.    GetFileDateTime(ihDRVFile, &uiTime, &uiDate);
  384.  
  385.    // display date
  386.    wsprintf((LPSTR)szBuffer, "%d/%d/%d", (uiDate<<7)>>12, (uiDate<<11)>>11, (uiDate>>9)+80);
  387.    TextOut(hDC, ixPos, iyPos+=iyOrg, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));  
  388.  
  389.    // close the file
  390.    _lclose(ihDRVFile);
  391.  
  392.    // check if bad driver
  393.    if (IsBadDRV((LPSTR)szDriver))
  394.    {
  395.       TextOut(hDC, ixPos, iyPos+=iyOrg, (LPSTR)"Driver is considered too buggy concerning DeviceCapabilities!", 61);
  396.       return FALSE;
  397.    }
  398.  
  399.    // get address of DeviceCapabilities function
  400.    lpfnDeviceCaps =  (LPFNDEVCAPS) GetProcAddress (hDriver, "DeviceCapabilities");
  401.    if (lpfnDeviceCaps)
  402.    {
  403.       // get driver version
  404.       dwBufSize = lpfnDeviceCaps ((LPSTR)szDevice, (LPSTR)szOutput, (WORD)DC_DRIVER,
  405.                                   (LPSTR)NULL, (LPDEVMODE)NULL);
  406.  
  407.       // display driver version
  408.       wsprintf((LPSTR)szBuffer, "%lx", dwBufSize);
  409.       TextOut(hDC, ixPos, iyPos+=iyOrg, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));  
  410.    }
  411.    else
  412.       TextOut(hDC, ixPos, iyPos+=iyOrg, (LPSTR)"DeviceCapabilities is not supported by driver!", 46);
  413.  
  414.    return (bResult);
  415.  } //*** DumpDriverInfo
  416.  
  417.  
  418. //*************************************************************
  419. //
  420. //  DumpPaperInfo
  421. //
  422. //  Purpose: This function retrieves driver information (paper sizes,
  423. //           paper extents) from the driver.
  424. //
  425. //
  426. //  Parameters:
  427. //      HDC hDC
  428. //      
  429. //
  430. //  Return: (BOOL)
  431. //
  432. //
  433. //  Comments:
  434. //
  435. //
  436. //  History:    Date       Author     Comment
  437. //              1/29/92    Don Miller
  438. //*************************************************************
  439.  
  440. BOOL DumpPaperInfo(HDC hDC)
  441. {
  442.    LPFNDEVCAPS lpfnDeviceCaps;
  443.    DWORD       dwBufSize1 = 0, dwBufSize2 = 0;
  444.    BOOL        bResult = 1;
  445.    WORD FAR    *pawPaperList;
  446.    HANDLE      hPaperList, hPaperDims;
  447.    POINT FAR   *paptPaperList;
  448.    char        szBuffer[64];
  449.    int         i, ixPos, iyPos, iyOrg;
  450.  
  451.    // check if bad driver
  452.    if (IsBadDRV((LPSTR)szDriver))
  453.    {
  454.       TextOut(hDC, 10, 10, (LPSTR)"Driver is considered too buggy concerning DeviceCapabilities!", 61);
  455.       return FALSE;
  456.    }
  457.  
  458.    // get address of DeviceCapabilities function
  459.    lpfnDeviceCaps = (LPFNDEVCAPS) GetProcAddress (hDriver, "DeviceCapabilities");
  460.    if (lpfnDeviceCaps)
  461.    {
  462.        // set column position
  463.        ixPos = cxChar;
  464.        iyPos = 0;
  465.  
  466.        // display heading
  467.        DisplayTextHeader(hDC, ixClient/2, iyPos, (LPSTR)"Paper Sizes Info");
  468.  
  469.        // set column position
  470.        iyOrg = cyChar;
  471.        iyPos = iyOrg;
  472.  
  473.        // get number of paper sizes
  474.        dwBufSize1 = lpfnDeviceCaps ((LPSTR)szDevice, (LPSTR)szOutput, (WORD)DC_PAPERS,
  475.                                     (LPSTR)NULL, (LPDEVMODE)NULL);
  476.  
  477.        // get paper dimensions
  478.        dwBufSize2 = lpfnDeviceCaps ((LPSTR)szDevice, (LPSTR)szOutput, (WORD)DC_PAPERSIZE,
  479.                                     (LPSTR)NULL, (LPDEVMODE)NULL);
  480.  
  481.        // allocate space for paper sizes
  482.        hPaperList   = GlobalAlloc(GMEM_MOVEABLE, dwBufSize1*sizeof(WORD));
  483.        pawPaperList = (WORD FAR *) GlobalLock(hPaperList);
  484.  
  485.        // allocate space for paper dimensions
  486.        hPaperDims    = GlobalAlloc(GMEM_MOVEABLE, dwBufSize2*sizeof(POINT));
  487.        paptPaperList = (POINT FAR *) GlobalLock(hPaperDims);
  488.  
  489.        // fill buffer with paper list
  490.        lpfnDeviceCaps ((LPSTR)szDevice, (LPSTR)szOutput, (WORD)DC_PAPERS,
  491.                        (LPSTR)pawPaperList, (LPDEVMODE)NULL);
  492.  
  493.        // fill buffer with paper dimensions
  494.        lpfnDeviceCaps ((LPSTR)szDevice, (LPSTR)szOutput, (WORD)DC_PAPERSIZE,
  495.                        (LPSTR)paptPaperList, (LPDEVMODE)NULL);
  496.  
  497.        TextOut(hDC, ixPos, iyPos+=iyOrg, (LPSTR)"Supported Paper Sizes:", 22);  
  498.        ixPos = LOWORD(GetTextExtent(hDC, (LPSTR)"Supported Paper Sizes:  ", 24));  
  499.  
  500.        // display results
  501.        if (dwBufSize1 < MAX_AMOUNT)
  502.        {
  503.          for (i=0; i < (int)dwBufSize1; i++)
  504.          {
  505.             if ((pawPaperList[i] < MAX_PAPERS) && (pawPaperList[i] > 0))
  506.                wsprintf((LPSTR)szBuffer, "%u (%d,%d) %s ", pawPaperList[i],
  507.                         paptPaperList[i].x, paptPaperList[i].y, (LPSTR)szPaperList[pawPaperList[i]]);
  508.  
  509.             else
  510.                wsprintf((LPSTR)szBuffer, "%u (%d,%d) %s ", pawPaperList[i],
  511.                         paptPaperList[i].x, paptPaperList[i].y, (LPSTR)szPaperList[0]);
  512.  
  513.             TextOut(hDC, ixPos, iyPos, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));  
  514.             iyPos += cyChar;
  515.          }
  516.        }
  517.        else
  518.          TextOut(hDC, ixPos, iyPos, (LPSTR)"Driver gave bad info!", 21);  
  519.  
  520.        // set column position
  521.        ixPos = cxChar;
  522.        TextOut(hDC, ixPos, iyPos+=iyOrg, (LPSTR)"Paper Extents:", 14);  
  523.        ixPos = LOWORD(GetTextExtent(hDC, (LPSTR)"Supported Paper Sizes:  ", 24));  
  524.  
  525.        // get min paper extent
  526.        dwBufSize1 = lpfnDeviceCaps ((LPSTR)szDevice, (LPSTR)szOutput, (WORD)DC_MINEXTENT,
  527.                                     (LPSTR)NULL, (LPDEVMODE)NULL);
  528.  
  529.        // display minimum paper extent
  530.        wsprintf((LPSTR)szBuffer, "Min X = %d  Min Y = %d", LOWORD(dwBufSize1),
  531.                 HIWORD(dwBufSize1));
  532.        TextOut(hDC, ixPos, iyPos, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));  
  533.  
  534.        // get max paper extent
  535.        dwBufSize1 = lpfnDeviceCaps ((LPSTR)szDevice, (LPSTR)szOutput, (WORD)DC_MAXEXTENT,
  536.                                     (LPSTR)NULL, (LPDEVMODE)NULL);
  537.  
  538.        // display maximum paper extent
  539.        wsprintf((LPSTR)szBuffer, "Max X = %d  Max Y = %d", LOWORD(dwBufSize1),
  540.                 HIWORD(dwBufSize1));
  541.        TextOut(hDC, ixPos, iyPos+=cyChar, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));  
  542.  
  543.        // clean up
  544.        GlobalUnlock(hPaperList);
  545.        GlobalUnlock(hPaperDims);
  546.        GlobalFree(hPaperList);
  547.        GlobalFree(hPaperDims);
  548.    }
  549.    else
  550.       TextOut(hDC, 10, 10, (LPSTR)"DeviceCapabilities is not supported by driver!", 46);
  551.  
  552.    return (bResult);
  553. } //*** DumpPaperInfo
  554.  
  555.  
  556. //*************************************************************
  557. //
  558. //  DumpBinInfo
  559. //
  560. //  Purpose:  This function retrieves driver information (bin
  561. //            numbers, bin names) from the driver.
  562. //
  563. //
  564. //  Parameters:
  565. //      HDC hDC
  566. //      
  567. //
  568. //  Return: (BOOL)
  569. //
  570. //
  571. //  Comments:
  572. //
  573. //
  574. //  History:    Date       Author     Comment
  575. //              1/29/92    Don Miller
  576. //*************************************************************
  577.  
  578. BOOL DumpBinInfo(HDC hDC)
  579. {
  580.    LPFNDEVCAPS lpfnDeviceCaps;
  581.    DWORD       dwBufSize = 0, dwMemSize;
  582.    BOOL        bResult = 1;
  583.    char        szBuffer[64];
  584.    int         i, ixPos, iyPos, iyOrg;
  585.    WORD FAR    *pawBinList;
  586.    HANDLE      hBinList;
  587.    LPSTR       lpstrBinNames;
  588.    short FAR   *sBinNameNums;
  589.    LPSTR       lpstrBinNameList;
  590.  
  591.    // check if bad driver
  592.    if (IsBadDRV((LPSTR)szDriver))
  593.    {
  594.       TextOut(hDC, 10, 10, (LPSTR)"Driver is considered too buggy concerning DeviceCapabilities!", 61);
  595.       return FALSE;
  596.    }
  597.  
  598.    // get address of DeviceCapabilities function
  599.    lpfnDeviceCaps =  (LPFNDEVCAPS) GetProcAddress (hDriver, "DeviceCapabilities");
  600.    if (lpfnDeviceCaps)
  601.    {
  602.        ixPos = cxChar;
  603.        iyPos = 0;
  604.  
  605.        // display header text centered
  606.        DisplayTextHeader(hDC, ixClient/2, iyPos, (LPSTR)"Bin Info");
  607.  
  608.        // set column position
  609.        iyOrg = cyChar;
  610.        iyPos = iyOrg;
  611.  
  612.        // get number of bins
  613.        dwBufSize = lpfnDeviceCaps ((LPSTR)szDevice, (LPSTR)szOutput, (WORD)DC_BINS,
  614.                                    (LPSTR)NULL, (LPDEVMODE)NULL);
  615.  
  616.        hBinList   = GlobalAlloc(GMEM_MOVEABLE, dwBufSize*sizeof(WORD));
  617.        pawBinList = (WORD FAR *) GlobalLock(hBinList);
  618.  
  619.        // fill buffer with bin list
  620.        lpfnDeviceCaps ((LPSTR)szDevice, (LPSTR)szOutput, (WORD)DC_BINS,
  621.                        (LPSTR)pawBinList, (LPDEVMODE)NULL);
  622.  
  623.        TextOut(hDC, ixPos, iyPos+=iyOrg, (LPSTR)"Supported Bin Types:", 20);  
  624.        ixPos = LOWORD(GetTextExtent(hDC, (LPSTR)"Supported Bin Types:  ", 22));  
  625.  
  626.        // display bin info
  627.        // protects from bad drivers
  628.        if ((dwBufSize > 0) && (dwBufSize < MAX_AMOUNT))
  629.        {
  630.          for (i=0; i < (int)dwBufSize; i++)
  631.          {
  632.             if (pawBinList[i] < MAX_AMOUNT)  // default bins
  633.             {
  634.                if (pawBinList[i] < MAX_BINS)
  635.                   wsprintf((LPSTR)szBuffer, "%u  %s ", pawBinList[i], (LPSTR)szBinList[pawBinList[i]]);
  636.                else
  637.                   wsprintf((LPSTR)szBuffer, "%u  %s ", pawBinList[i], (LPSTR)szBinList[0]);
  638.             }
  639.             else  // device specific bins
  640.                wsprintf((LPSTR)szBuffer, "%u  %s ", pawBinList[i], (LPSTR)szBinList[15]);
  641.  
  642.  
  643.             TextOut(hDC, ixPos, iyPos, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));  
  644.             iyPos += cyChar;
  645.          }
  646.        }
  647.        else if (dwBufSize == 0)  // no bins
  648.          TextOut(hDC, ixPos, iyPos, (LPSTR)"None", 4);  
  649.  
  650.        else
  651.        {
  652.          TextOut(hDC, ixPos, iyPos, (LPSTR)"Driver gave bad info!", 21);  
  653.          iyPos += cyChar;
  654.        }
  655.        // clean up
  656.        GlobalUnlock(hBinList);
  657.        GlobalFree(hBinList);
  658.  
  659.        // get number of named bins
  660.        dwBufSize = lpfnDeviceCaps ((LPSTR)szDevice, (LPSTR)szOutput, (WORD)DC_BINNAMES,
  661.                                    (LPSTR)NULL, (LPDEVMODE)NULL);
  662.  
  663.        if ((dwBufSize > 0) && (dwBufSize < MAX_AMOUNT))
  664.        {
  665.          // get buffer size
  666.          dwMemSize = dwBufSize * (sizeof(short) + (CCHBINNAME*sizeof(char)));
  667.  
  668.          // allocate space for bin names
  669.          hBinList      = GlobalAlloc(GMEM_MOVEABLE, dwMemSize);
  670.          lpstrBinNames = GlobalLock(hBinList);
  671.  
  672.          // fill buffer with bin names
  673.          lpfnDeviceCaps ((LPSTR)szDevice, (LPSTR)szOutput, (WORD)DC_BINNAMES,
  674.                          (LPSTR)lpstrBinNames, (LPDEVMODE)NULL);
  675.  
  676.          // display field identifier
  677.          ixPos = cxChar;
  678.          iyPos += cyChar;;
  679.  
  680.          TextOut(hDC, ixPos, iyPos, (LPSTR)"Named bins:", 11);
  681.          ixPos = LOWORD(GetTextExtent(hDC, (LPSTR)"Supported Bin Types:  ", 22));  
  682.  
  683.          // display bin identifier number and bin name
  684.          for (i=0; i < (int)dwBufSize; i++)
  685.          {
  686.             sBinNameNums     = (short FAR *)(lpstrBinNames + (dwBufSize*CCHBINNAME));
  687.             lpstrBinNameList = lpstrBinNames;
  688.  
  689.             wsprintf((LPSTR)szBuffer, "%d %s", sBinNameNums[i],
  690.                      (LPSTR)lpstrBinNameList + (CCHBINNAME*i));
  691.  
  692.             TextOut(hDC, ixPos, iyPos, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));  
  693.             iyPos += cyChar;;
  694.          }
  695.  
  696.          // clean up
  697.          GlobalUnlock(hBinList);
  698.          GlobalFree(hBinList);
  699.        }
  700.    }
  701.    else
  702.       TextOut(hDC, 10, 10, (LPSTR)"DeviceCapabilities is not supported by driver!", 46);
  703.  
  704.    return (bResult);
  705. } //*** DumpBinInfo
  706.  
  707.  
  708. //*************************************************************
  709. //
  710. //  DumpDevmodeInfo
  711. //
  712. //  Purpose: This function dumps all the device-independent 
  713. //           information of the DEVMODE structure.
  714. //        
  715. //
  716. //
  717. //  Parameters:
  718. //      HWND hWnd
  719. //      HDC hDC
  720. //      
  721. //
  722. //  Return: (BOOL)
  723. //
  724. //
  725. //  Comments:
  726. //
  727. //
  728. //  History:    Date       Author     Comment
  729. //              1/29/92    Don Miller
  730. //*************************************************************
  731.  
  732. BOOL DumpDevmodeInfo(HWND hWnd, HDC hDC)
  733. {
  734.    LPFNDEVMODE lpfnDeviceMode;
  735.    DWORD       dwBufSize = 0;
  736.    BOOL        bResult;
  737.    char        szBuffer[64];
  738.    int         i, ixPos, ixRightPos, iyPos, iyOrg;
  739.    HANDLE      hDM;
  740.    LPDEVMODE   lpDM;
  741.  
  742.    // get address of ExtDeviceMode function
  743.    lpfnDeviceMode =  (LPFNDEVMODE) GetProcAddress (hDriver, "ExtDeviceMode");
  744.    if (lpfnDeviceMode)
  745.    {
  746.        // get DEVMODE stuff from driver
  747.        dwBufSize = lpfnDeviceMode ((HWND)hWnd, (HANDLE)hDriver,
  748.                                    (LPDEVMODE)NULL, (LPSTR)szDevice,
  749.                                    (LPSTR)szOutput, (LPDEVMODE)NULL,
  750.                                    (LPSTR)NULL, (WORD)0);
  751.  
  752.        // alloc space for devmode stuff
  753.        hDM  = GlobalAlloc(GMEM_MOVEABLE, dwBufSize);
  754.        lpDM = (LPDEVMODE)GlobalLock(hDM);
  755.  
  756.        // fill DEVMODE buffer
  757.        dwBufSize = lpfnDeviceMode ((HWND)hWnd, (HANDLE)hDriver,
  758.                                    (LPDEVMODE)lpDM, (LPSTR)szDevice,
  759.                                    (LPSTR)szOutput, (LPDEVMODE)NULL,
  760.                                    (LPSTR)NULL, (WORD)DM_COPY);
  761.  
  762.        // set column position
  763.        ixPos = cxChar;
  764.        iyPos = 0;
  765.  
  766.        // display header text centered
  767.        DisplayTextHeader(hDC, ixClient/2, iyPos, (LPSTR)"DEVMODE Info");
  768.  
  769.        iyPos = iyOrg = 2*cyChar;
  770.        ixRightPos = LOWORD(GetTextExtent(hDC, (LPSTR)"dmDefaultSource:", 16)) + 2*cxChar;
  771.  
  772.        // display devmode fields
  773.        for (i=0; i < MAX_DEVMODE; i++)
  774.        {
  775.          TextOut(hDC, ixPos, iyPos, (LPSTR)szDevModeList[i], lstrlen((LPSTR)szDevModeList[i]));
  776.  
  777.          switch (i)
  778.          {
  779.             case 0:
  780.                //get DEVMODE's first field
  781.                wsprintf((LPSTR)szBuffer, "%s", (LPSTR)lpDM->dmDeviceName );
  782.                break;
  783.  
  784.             case 1:
  785.                //get DEVMODE's second field
  786.                wsprintf((LPSTR)szBuffer, "%xh", (WORD)lpDM->dmSpecVersion);
  787.                break;
  788.  
  789.             case  2:
  790.                //get DEVMODE's third field
  791.                wsprintf((LPSTR)szBuffer, "%xh", (WORD)lpDM->dmDriverVersion);
  792.                break;
  793.  
  794.             case  3:
  795.                //get DEVMODE's fourth field
  796.                wsprintf((LPSTR)szBuffer, "%d bytes", (WORD)lpDM->dmSize);
  797.                break;
  798.  
  799.             case  4:
  800.                //get DEVMODE's fifth field
  801.                wsprintf((LPSTR)szBuffer, "%d bytes", (WORD)lpDM->dmDriverExtra);
  802.                break;
  803.  
  804.             case  5:
  805.                //get DEVMODE's sixth field
  806.                wsprintf((LPSTR)szBuffer, "%lu (bitfield)", (DWORD)lpDM->dmFields);
  807.                break;
  808.  
  809.             case  6:
  810.                //get DEVMODE's seventh field
  811.                if (lpDM->dmOrientation == 2)
  812.                   wsprintf((LPSTR)szBuffer, "%d DMORIENT_LANDSCAPE", (short)lpDM->dmOrientation);
  813.                else
  814.                   wsprintf((LPSTR)szBuffer, "%d DMORIENT_PORTRAIT", (short)lpDM->dmOrientation);
  815.                break;
  816.  
  817.             case  7:
  818.                //get DEVMODE's eighth field
  819.                wsprintf((LPSTR)szBuffer, "%d %s", (short)lpDM->dmPaperSize,
  820.                         (LPSTR)szPaperList[lpDM->dmPaperSize]);
  821.                break;
  822.  
  823.             case  8:
  824.                //get DEVMODE's ninth field
  825.                wsprintf((LPSTR)szBuffer, "%d (tenths of a millimeter)", (short)lpDM->dmPaperLength);
  826.                break;
  827.  
  828.             case  9:
  829.                //get DEVMODE's tenth field
  830.                wsprintf((LPSTR)szBuffer, "%d (tenths of a millimeter)", (short)lpDM->dmPaperWidth);
  831.                break;
  832.  
  833.             case  10:
  834.                //get DEVMODE's eleventh field
  835.                wsprintf((LPSTR)szBuffer, "%d", (short)lpDM->dmScale);
  836.                break;
  837.  
  838.             case  11:
  839.                //get DEVMODE's twelveth field
  840.                wsprintf((LPSTR)szBuffer, "%d", (short)lpDM->dmCopies);
  841.                break;
  842.  
  843.             case  12:
  844.                //get DEVMODE's thirteenth field
  845.                if ((lpDM->dmDefaultSource >= 0) && (lpDM->dmDefaultSource < MAX_PAPERS))
  846.                   wsprintf((LPSTR)szBuffer, "%d %s", (short)lpDM->dmDefaultSource,
  847.                            (LPSTR)szBinList[lpDM->dmDefaultSource]);
  848.  
  849.                else if (lpDM->dmDefaultSource >= MAX_PAPERS)
  850.                   wsprintf((LPSTR)szBuffer, "%d %s", (short)lpDM->dmDefaultSource,
  851.                            (LPSTR)szPaperList[0]);
  852.  
  853.                else
  854.                   wsprintf((LPSTR)szBuffer, "%d %s", (short)lpDM->dmDefaultSource,
  855.                            (LPSTR)szBinList[15]);
  856.  
  857.                break;
  858.  
  859.             case  13:
  860.                //get DEVMODE's fourteenth field
  861.                if (lpDM->dmPrintQuality < 0)
  862.                   wsprintf((LPSTR)szBuffer, "%d %s", (short)lpDM->dmPrintQuality,
  863.                            (LPSTR)szPQualityList[-lpDM->dmPrintQuality]);
  864.  
  865.                else if (lpDM->dmPrintQuality >= 0)
  866.                   wsprintf((LPSTR)szBuffer, "%d %s", (short)lpDM->dmPrintQuality,
  867.                            (LPSTR)szPQualityList[0]);
  868.  
  869.                break;
  870.  
  871.             case 14:
  872.                // get DEVMODE's fifteenth field
  873.                if (lpDM->dmColor == DMCOLOR_MONOCHROME)
  874.                   wsprintf((LPSTR)szBuffer, "%d DMCOLOR_MONOCHROME", (short)lpDM->dmColor);
  875.  
  876.                else if (lpDM->dmColor == DMCOLOR_COLOR)
  877.                   wsprintf((LPSTR)szBuffer, "%d DMCOLOR_COLOR", (short)lpDM->dmColor);
  878.  
  879.                else
  880.                   wsprintf((LPSTR)szBuffer, "%d UNKNOWN", (short)lpDM->dmColor);
  881.  
  882.                break;
  883.  
  884.             case 15:
  885.                // get DEVMODE's sixteenth field
  886.                switch (lpDM->dmDuplex)
  887.                {
  888.                   case DMDUP_SIMPLEX:    
  889.                      wsprintf((LPSTR)szBuffer, "%d DMDUP_SIMPLEX", (short)lpDM->dmDuplex);
  890.                      break;
  891.  
  892.                   case DMDUP_VERTICAL:
  893.                      wsprintf((LPSTR)szBuffer, "%d DMDUP_VERTICAL", (short)lpDM->dmDuplex);
  894.                      break;
  895.  
  896.                   case DMDUP_HORIZONTAL:
  897.                      wsprintf((LPSTR)szBuffer, "%d DMDUP_HORIZONTAL", (short)lpDM->dmDuplex);
  898.                      break;
  899.  
  900.                   default:
  901.                      wsprintf((LPSTR)szBuffer, "%d UNKNOWN", (short)lpDM->dmDuplex);
  902.                      break;
  903.                }
  904.                break;
  905.  
  906.              default:
  907.                break;
  908.          }
  909.          TextOut(hDC, ixRightPos, iyPos, (LPSTR)szBuffer, lstrlen((LPSTR)szBuffer));  
  910.          iyPos += cyChar;
  911.        }
  912.        GlobalUnlock(hDM);
  913.        GlobalFree(hDM);
  914.    }
  915.    else
  916.       TextOut(hDC, 10, 10, (LPSTR)"ExtDeviceMode is not supported by driver!", 41);
  917.  
  918.    return (bResult);
  919. } //*** DumpDevmodeInfo
  920.  
  921.  
  922. //*************************************************************
  923. //
  924. //  DisplayTextHeader
  925. //
  926. //  Purpose: Displays header text centered
  927. //        
  928. //
  929. //
  930. //  Parameters:
  931. //      HDC hDC
  932. //      int ixPos
  933. //      int iyPos
  934. //      LPSTR lpstrHText
  935. //      
  936. //
  937. //  Return: (void)
  938. //
  939. //
  940. //  Comments:
  941. //
  942. //
  943. //  History:    Date       Author     Comment
  944. //              1/29/92    Don Miller
  945. //*************************************************************
  946.  
  947. void DisplayTextHeader(HDC hDC, int ixPos, int iyPos, LPSTR lpstrHText)
  948. {
  949.    WORD wOldFlags;
  950.  
  951.        // display header text centered
  952.        wOldFlags = SetTextAlign(hDC, TA_CENTER);
  953.        TextOut(hDC, ixPos, iyPos, lpstrHText, lstrlen(lpstrHText));
  954.        SetTextAlign(hDC, wOldFlags);
  955.  
  956. } //*** DisplayTextHeader
  957.  
  958.  
  959. //*************************************************************
  960. //
  961. //  IsBadDRV
  962. //
  963. //  Purpose: Checks list of known buggy drivers in DEVMODE.H 
  964. //        
  965. //
  966. //
  967. //  Parameters:
  968. //      LPSTR lpstrDRVName
  969. //      
  970. //
  971. //  Return: (BOOL)
  972. //
  973. //
  974. //  Comments:
  975. //
  976. //
  977. //  History:    Date       Author     Comment
  978. //              1/29/92    Don Miller
  979. //*************************************************************
  980.  
  981. BOOL IsBadDRV(LPSTR lpstrDRVName)
  982. {
  983.    int i = 0;
  984.    BOOL bBadDRV = FALSE;
  985.  
  986.    // checks to see if current printer choice is in list of bad
  987.    // drivers list in DEVMODE.H
  988.  
  989.    while ((i < 6) && (!bBadDRV))
  990.    {
  991.       if (!lstrcmp((LPSTR)szBadDrvs[i], lpstrDRVName))
  992.          bBadDRV = TRUE;
  993.  
  994.       i++;
  995.    }
  996.    return bBadDRV;
  997.  
  998. } //*** IsBadDRV
  999.  
  1000. /*** EOF: mainwnd.c ***/
  1001.